﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Security;
using System.Linq;

namespace ClubWebsite
{
    /// <summary>
    /// Summary description for WebService
    /// </summary>
    [WebService(Namespace = "http://www.everyonesclub.com/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    public class WebService : System.Web.Services.WebService
    {
        private class AuthorizedClient
        {
            public object ClientReference;
            public DateTime LastUTC;
        }
        private static List<AuthorizedClient> _authorisedClients = new List<AuthorizedClient>();

        [WebMethod]
        public bool IsAuthorised(object reference)
        {
            if (GetAuthorisedClientByReference(reference) != null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        [WebMethod]
        public bool Login(string email, string password, object reference)
        {
            bool credentialsMatch = Functions.GetDatabaseDataContext()
                    .Users
                    .Any(u => u.Email == email.Trim() && u.Password == password.Trim());
            if (credentialsMatch)
            {
                // Login details are correct
                AuthorizedClient authorizedClient = GetAuthorisedClientByReference(reference);
                if (authorizedClient != null)
                {
                    authorizedClient.LastUTC = DateTime.UtcNow;
                }
                else
                {
                    authorizedClient = new AuthorizedClient();
                    authorizedClient.ClientReference = reference;
                    authorizedClient.LastUTC = DateTime.UtcNow;
                    _authorisedClients.Add(authorizedClient);
                }
                return true;
            }
            return false;
        }

        [WebMethod]
        public List<Guid> GetListOfScrapes(object reference)
        {
            if (GetAuthorisedClientByReference(reference) != null)
            {
                return Functions.GetDatabaseDataContext()
                    .Scrapes
                    .Select(s => s.ID)
                    .ToList();
            }
            else
            {
                throw new ApplicationException("Please login first.");
            }
        }

        [WebMethod]
        public void UpdateLeagueStatistics(Guid leagueID, object reference)
        {
            if (GetAuthorisedClientByReference(reference) != null)
            {
                Functions.UpdateLeagueStatistics(leagueID);
            }
            else
            {
                throw new ApplicationException("Please login first.");
            }
        }

        [WebMethod]
        public void RunScrape(Guid scrapeID, object reference)
        {
            if (GetAuthorisedClientByReference(reference) != null)
            {
                Scrape scrape = Functions.GetDatabaseDataContext()
                    .Scrapes
                    .Where(s => s.ID == scrapeID)
                    .Single();
                ScrapeFunctions.ExecuteScrape(scrape.ID, null);
                Functions.UpdateLeagueStatistics(scrape.LeagueID.Value);
            }
            else
            {
                throw new ApplicationException("Please login first.");
            }
        }

        private AuthorizedClient GetAuthorisedClientByReference(object reference)
        {
            AuthorizedClient authorizedClientToRemove = null;
            foreach (AuthorizedClient authorizedClient in _authorisedClients)
            {
                if (authorizedClient.ClientReference.ToString() == reference.ToString())
                {
                    // Ensure the client hasn't taken too long between connections
                    if ((DateTime.UtcNow - authorizedClient.LastUTC).TotalMinutes < 5)
                    {
                        authorizedClient.LastUTC = DateTime.UtcNow;
                        return authorizedClient;
                    }
                    else
                    {
                        // Remove the client from the list
                        authorizedClientToRemove = authorizedClient;
                        break;
                    }
                }
            }
            if (authorizedClientToRemove != null)
            {
                _authorisedClients.Remove(authorizedClientToRemove);
            }
            return null;
        }
    }
}
